package main

import "fmt"

// 接口
// 接口是一组方法签名。
// 当类型为接口中的所有方法提供定义时，它被称为实现该接口。
// 它与OOP非常相似。接口指定了类型应该具有的方法，类型决定了如何实现这些方法。
// 接口是隐式实现的。
// 接口可以被任何类型实现。

// 一般来说，接口的名称由方法名称的后缀“er”组成， 如Printer, Reader, Writer, etc.
// 1. 一个类型不必明确声明它实现了一个接口：接口是隐式实现的。多种类型可以实现同一个接口。
// 2. 实现接口的类型还可以具有其他的功能。
// 3. 一个类型可以实现多个接口。
// 4. 接口类型可以包含对实现该接口的任何类型的实例引用

// 在Go语言中，当car结构体实现了vehicle接口要求的所有方法（这里只有accelerate()一个方法）时，car就隐式实现了vehicle接口。
// 因此，car类型的实例可以被视为vehicle类型的实例，并且可以作为参数传递给foo函数。
// 这就是接口的隐式实现。
type vehicle interface {
	accelerate()
}

func foo(v vehicle) {
	fmt.Println(v)
}

type car struct {
	model string
	color string
}

func (c car) accelerate() {
	fmt.Println("Car is accelerating")
}

type toyota struct {
	model string
	color string
	speed int
}

func (t toyota) accelerate() {
	fmt.Println("Toyota is accelerating")
}

func main() {
	c1 := car{model: "Camry", color: "Red"}
	t1 := toyota{model: "Camry", color: "Red", speed: 60}
	c1.accelerate()
	t1.accelerate()
	foo(c1)
	foo(t1)
}
